#include <QtCore>
#include <QtNetwork>
#include "spyserver.h"
#include "spythread.h"

SpyServer::SpyServer(QObject *parent) :
    QTcpServer(parent)
{
    qDebug() << "spawning new SpyServer...";

    // set up system monitor
    spyMon = new SpyMon(this);
    connect(this,SIGNAL(log(int,QString)),spyMon,SLOT(logFromServer(int,QString)));

    // start network server
    if (!startNet()) {
        emit log(0,"failed to start network");
        QTimer::singleShot(1, this->parent(), SLOT(quit()));
    } else {
        emit log(4,"started listening on network");
    }

    // constructor complete
    emit log(5,"construction complete");
}

SpyServer::~SpyServer()
{
    emit log(4,"destroyed");
}

bool SpyServer::startNet()
{
    // start network server
    if (!listen(QHostAddress::Any,50000)) {
        QString e = "unable to start server, error:" + errorString();
        emit log(0,e);
        return 0;
        //QTimer::singleShot(1, this->parent(), SLOT(quit()));
    }
    QString ipAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // use the first non-localhost IPv4 address
    for (int i = 0; i < ipAddressesList.size(); ++i) {
        if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
            ipAddressesList.at(i).toIPv4Address()) {
            ipAddress = ipAddressesList.at(i).toString();
            break;
        }
    }
    // if we did not find one, use IPv4 localhost
    if (ipAddress.isEmpty())
        ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
    QString status = "server running at IP " + ipAddress + " port " + QString::number(serverPort());
    emit log(4,status);
    return 1;
}

void SpyServer::incomingConnection(int socketDescriptor)
{
    QString status = "incomingConnection sd: " + QString::number(socketDescriptor);
    emit log(4,status);

    SpyThread *spyThread = new SpyThread(socketDescriptor);
    emit log(5,"created new SpyThread(sockDesc)");
    spyThread->connect(spyThread,SIGNAL(finished()),spyThread, SLOT(deleteLater()));
    spyMon->connect(spyThread,SIGNAL(log(int,QString)),SLOT(logFromThread(int,QString)));
    spyThread->moveToThread(spyThread);
    emit log(5,"moved spyThread signals");
    spyThread->start();
    emit log(5,"started thread");
}
